package com.mdxx.xczd.manager;

import android.content.Context;
import android.os.Handler;
import com.mdxx.xczd.app.App;
import com.mdxx.xczd.app.UrlValue;
import com.mdxx.xczd.bean.ChatGroupBean;
import com.mdxx.xczd.chat.websocket.autobahn.WebSocketConnection;
import com.mdxx.xczd.chat.websocket.autobahn.WebSocketConnectionHandler;
import com.mdxx.xczd.chat.websocket.autobahn.WebSocketException;
import com.mdxx.xczd.chat.websocket.autobahn.WebSocketOptions;
import com.mdxx.xczd.chat.websocket.json.ParseJson;
import com.mdxx.xczd.utils.GsonUtil;
import com.orhanobut.logger.Logger;
import net.majorkernelpanic.streaming.Session;
import net.majorkernelpanic.streaming.SessionBuilder;
import net.majorkernelpanic.streaming.rtsp.RtspClient;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class RtspMenager {

	private Context context;
	private String wsAudioUrl = "";//连接语音服务器的URL
	private Session mSession;
	private RtspClient mClient;
	private WebSocketConnection connection = null;
	private ParseJson serverDataParse; // 解析从服务端收到的json数据
	private String empNum     = "0004";//该员工的工号
	private int roleId        = 1;//该员工的角色编号，用于不同的权限
	private String cgNum      = "20161";//该员工所处的对讲组编号
	private boolean isDeny=false;
	private boolean isRevoke=false;
	private boolean running=false;
	private long lastSendTime;  
	private ChatGroupBean chatGroupBean;
	private boolean isTimeout = false;
	private static RtspMenager rtspMenager;
	private AudioManagerUtil audioManager;
	private VlcManager vlcManager;
	private KeepAliveWatchDog keepAliveWatchDog ;
	private Thread keepAliveThread ;

	public static RtspMenager getInstance(Context context){
		if(rtspMenager == null){
			synchronized (AudioManagerUtil.class) {
				if(rtspMenager == null){
					rtspMenager = new RtspMenager(context);
				}
			}
		}
		return rtspMenager;
	}	

	private RtspMenager(Context context){
		this.context = context;
		initManager();
	}

	private void initManager(){
		audioManager = AudioManagerUtil.getInstance(context);
		vlcManager = VlcManager.getInstance(context);
	}

	public void initPlay() {
		empNum = App.USERID;
		if(chatGroupBean != null){
			cgNum = chatGroupBean.getCgNum();
		}
		initWebSocket();
		if (null == connection) {
			connection = new WebSocketConnection();
		}		
		mSession = SessionBuilder.getInstance()
				.setContext(App.getAppContext())
				.setAudioEncoder(SessionBuilder.AUDIO_AMRNB)
				.build();
		mClient = new RtspClient();
		mClient.setSession(mSession);
		mClient.setCallback(rtspCallback);	
		if (!connection.isConnected()) {
			webSocketConn();
		}
	}

	private void initWebSocket() {
		wsAudioUrl=UrlValue.wsUrl+"/ws?user="
				+ empNum+ "&AUTH="+roleId + "&group="+cgNum;
	}

	public void disconnect(){
		connection.disconnect();
		connection = null;
	}
	public void webSocketConn() {
		try {
			serverDataParse = new ParseJson();
			WebSocketOptions webSocketOptions = new WebSocketOptions();
			webSocketOptions.setReconnectInterval(1000);
			connection.connect(wsAudioUrl, WebSocketConnectionHandler, webSocketOptions);
		} catch (WebSocketException e) {
			e.printStackTrace();
		}
	}

	private WebSocketConnectionHandler WebSocketConnectionHandler = new WebSocketConnectionHandler(){
		@Override
		public void onBinaryMessage(byte[] payload) {
			if (payload[0] == 0x00) {
				InputStream is = new ByteArrayInputStream(payload, 4, payload.length - 4);
				serverDataParse.jsonParse(is);
				if (serverDataParse.getType().equals("TB_Request")) {
					String TYPE=serverDataParse.getTYPE();
					if(serverDataParse.getTYPE().equals("TB_Granted")){
						sendToServer("TB_ACK",false,0,null);
					}else if(serverDataParse.getTYPE().equals("TB_Deny")){
						//因为对讲请求被拒，所以按键抬起动作无效
						isDeny=true;
					}else if(serverDataParse.getTYPE().equals("TB_Revoke")){
						isRevoke=true;
						stopPushAudioStream();
					}
				}
				if (serverDataParse.getType().equals("TB_ACK")) {// 有人讲话，如果是自己则开始采集语音上传
					String TYPE=serverDataParse.getTYPE();
					//如果是自己则开始录音上传流，否则开始播放他人的流
					if(serverDataParse.getTYPE().equals("TB_Taken")){
						if(empNum.equals(serverDataParse.getUSER())){
							startPushAudioStream(UrlValue.streamUrl+"/"+empNum+".sdp");
						}else{
							String rtspUrl=serverDataParse.getRTSP();
							startPlayAudio(rtspUrl);
						}
					}else if(serverDataParse.getTYPE().equals("TB_Revoke")){
						isRevoke=true;
						stopPushAudioStream();
					}else if(serverDataParse.getTYPE().equals("TB_Idle")){
					}
				}
				if (serverDataParse.getType().equals("TB_Release")) {
					String TYPE=serverDataParse.getTYPE();
					if(serverDataParse.getTYPE().equals("TB_Idle")){
						if(empNum.equals(serverDataParse.getUSER())){
							stopPushAudioStream();
						}else{
							new Handler().postDelayed(new Runnable() {
								@Override
								public void run() {
									vlcManager.stopPlayAudio();
									/*mediaPlayerManager.stopPlayAudio();*/
								}
							}, 2000);
						}
					}
				}

				if (serverDataParse.getType().equals("TB_Notice")) {
					String TYPE=serverDataParse.getTYPE();
					if(serverDataParse.getTYPE().equals("TB_Notice")){
						updateChatGroup();
					}
				}

				if (serverDataParse.getType().equals("TB_CancelAlarm")) {
					String TYPE=serverDataParse.getTYPE();
					if(serverDataParse.getTYPE().equals("TB_CancelAlarm")){
					}
				}
				if (serverDataParse.getType().equals("TB_HreatBeat")) {
					isTimeout = false;
				}
			} 
		}

		@Override
		public void onClose(int code, String reason) {
			if(!keepAliveThread.interrupted()){
				keepAliveThread.interrupt();
			}
		}

		@Override
		public void onOpen() {
			isTimeout = false;
			start();
		}

		@Override
		public void onRawTextMessage(byte[] payload) {
		}

		@Override
		public void onTextMessage(String payload) {
		}
	};	

	/**
	 * 开始播放RTSP音频
	 */
	protected void startPlayAudio(String rtspUrl) {
		vlcManager.startPlayAudio(rtspUrl);
		/*mediaPlayerManager.stopPlayAudio();
		if (!TextUtils.equals(rtspUrl, "")) {
			mediaPlayerManager.startPlayAudio(rtspUrl);
		}*/
	}

	public void stopPushAudioStream() {
		mClient.stopStream();		//关闭语音流
	}

	public void startPushAudioStream(String server) {   
		String serverAddress, ip, port, path;
		serverAddress = server;
		Pattern uri = Pattern.compile("rtsp://(.+):(\\d*)/(.+)");
		Matcher m = uri.matcher(serverAddress);
		m.find();
		ip = m.group(1);
		port = m.group(2);
		path = m.group(3);
		mClient.setCredentials("", "");
		mClient.setServerAddress(ip, Integer.parseInt(port));
		mClient.setStreamPath("/" + path);
		mClient.startStream();
		new Handler().postDelayed(new Runnable(){   
			@Override
			public void run() {   
				audioManager.teamTouchPlayer();
			}   
		}, 500);
		
	}


	public boolean down(){
		sendToServer("TB_Request",false,0,null);
		return true;
	}

	public void up(){
		if(isDeny||isRevoke){//被拒\强制释放\被高权限抢
			sendToServer("TB_Release",false,0,null);//非正常释放
			isDeny=false;
			isRevoke=false;
		}else{
			sendToServer("TB_Release",true,0,null);//正常释放
		}
	}

	public void sendToServer(String type, boolean b,int alarmType,String alarmNUM) {
		JSONObject jsonobject = new JSONObject();
		try {
			String rtsp=UrlValue.streamUrl+"/"+empNum+".sdp";
			jsonobject.put("type", type);// 类型
			jsonobject.put("AUTH", roleId);// 用户权限
			jsonobject.put("USER", empNum);// 用户工号
			if(type.equals("TB_Request")){//对讲的请求
			}else if(type.equals("TB_ACK")){//对讲确认
				jsonobject.put("RTSP", rtsp);// RTSP
			}else if(type.equals("TB_Release")){//对讲释放
				if(b){
					jsonobject.put("RELEASE", 1);// 正常释放
				}else{
					jsonobject.put("RELEASE", 0);// 被动释放：此释放无效
				}
			}else if(type.equals("TB_ALARM")){//警报
				jsonobject.put("RTSP", rtsp);// RTSP
				jsonobject.put("ALARM_TYPE", alarmType);// RTSP
				jsonobject.put("ALARM_NUM", alarmNUM);// RTSP
			}else if(type.equals("TB_Notice")){//对讲组有变化，提示更新，模拟值班员发出的
			}else{
				return;
			}
		} catch (JSONException e) {
			e.printStackTrace();
		}  
		byte[] textType = new byte[] { 0x00, 0x00, 0x00, 0x00 };
		byte[] textParam = jsonobject.toString().getBytes();
		byte[] textMessage = new byte[textType.length + textParam.length];
		System.arraycopy(textType, 0, textMessage, 0, textType.length);
		System.arraycopy(textParam, 0, textMessage, textType.length, textParam.length);
		connectionWebSocket();
		Logger.d("connection="+connection);
		connection.sendBinaryMessage(textMessage);
	}

	public void sendToServer() {
		JSONObject jsonobject = new JSONObject();
		try {
			jsonobject.put("type", "TB_HreatBeat");// 类型
			jsonobject.put("AUTH", roleId);// 用户权限
			jsonobject.put("USER", empNum);// 用户工号

		} catch (JSONException e) {
			e.printStackTrace();
		}  
		byte[] textType = new byte[] { 0x00, 0x00, 0x00, 0x00 };
		byte[] textParam = jsonobject.toString().getBytes();
		byte[] textMessage = new byte[textType.length + textParam.length];
		System.arraycopy(textType, 0, textMessage, 0, textType.length);
		System.arraycopy(textParam, 0, textMessage, textType.length,
				textParam.length);
		if (!connection.isConnected()) {
			webSocketConn();
		}
		connection.sendBinaryMessage(textMessage);
	}


	public void start(){
		keepAliveWatchDog = new KeepAliveWatchDog();
		keepAliveThread = new Thread(keepAliveWatchDog);
		if(running) return;
		lastSendTime=System.currentTimeMillis();  
		running=true;
		Logger.d("="+keepAliveThread);
		if(!keepAliveThread.isAlive()){
			keepAliveThread.start();
		}
	}  
	class KeepAliveWatchDog implements Runnable{
		long checkDelay = 5000;  
		long keepAliveDelay = 10000;  
		public void run() {  
			while(running){  
				if(System.currentTimeMillis() - lastSendTime > keepAliveDelay){ 
					if(!isTimeout){
						sendToServer();  
					}else{
						Logger.d("webSocketConn");
						//					webSocketConn();
					}
					lastSendTime = System.currentTimeMillis();
					isTimeout = true;

				}else{ 
					try {  
						Thread.sleep(checkDelay);  
					} catch (InterruptedException e) {  
						e.printStackTrace();  
						stop();  
					}  
				}  
			}  
		}  
	}

	public void stop(){  
		if(running)
			running = false;  
	}  

	private RtspClient.Callback rtspCallback = new RtspClient.Callback(){

		@Override
		public void onRtspUpdate(int message, Exception exception) {
		}
	};

	public void connectionWebSocket(){
		if (!connection.isConnected()) {
			webSocketConn();
		}
	}

	/**
	 * 由于后台调整对讲组的结构  终端重新更新对讲组信息
	 */
	public void updateChatGroup() {
		String url=UrlValue.url+"/RelicProtectionAdmin/AndroidTaskServlet?action=chatGroup&empNum="+App.USERID;
		getGroupInfo(url);
	}

	private void getGroupInfo(String url){
		Logger.d("url="+url);
		OkHttpClient mOkHttpClient = new OkHttpClient();
		final Request request = new Request.Builder()
		.url(url)
		.build();
		Call call = mOkHttpClient.newCall(request); 
		call.enqueue(new Callback(){

			@Override
			public void onFailure(Call arg0, IOException arg1) {

			}

			@Override
			public void onResponse(Call arg0, Response arg1) throws IOException {
				String result = arg1.body().string();
				Logger.d("result="+result);
				JSONObject obj_result;
				String data;
				int code;
				try {
					obj_result = new JSONObject(result);
					code = obj_result.optInt("code");
					if(code == 0){					
						data = obj_result.optString("data");
						chatGroupBean = GsonUtil.jsonToBean(data, ChatGroupBean.class);
						initPlay();
					}
				} catch (JSONException e) {
					e.printStackTrace();
				}
			}});             
	}
}
